package isssr.bean.boundary;

import isssr.bean.control.ActivityGOControl;
import isssr.bean.entity.CurrentUser;
import isssr.bean.entity.GoalStatus;
import isssr.bean.entity.OrganizationalGoal;
import isssr.bean.entity.User;
import isssr.bean.exception.GoalElicitationException;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;


public class ActivityGOBoundary implements Serializable {

	/**
	 * 
	 */
	private static final long 	serialVersionUID = 2994427649901470209L;
	
	
	private boolean 			render_save_action;
	private boolean 			render_delete_action;
	private boolean 			render_close_action;
	private boolean 			render_goal;
	
	private Integer				id;
	private String 				title;
	private String 				description;
	private Integer 			priority;
	private GoalStatus			status;
	private String 				focus;
	private String 				object;
	private String 				magnitude;
	private String 				timeframe;
	private String 				organizationalScope;
	private String 				constraints;
	private String				relations;
	
	private User 				goalOwner;
	private User				goalEnactor;
	private List<User> 			superList;
		
	//injected beans
	private EnactorTable		select_enactor_boundary;
	private SuperTable			select_super_boundary;
	private ActivityGOControl 	go_activity_control;
	private ExplorerGOBoundary	explorer_boundary;
	private CurrentUser			current_user;
	
	public ActivityGOBoundary(){}
	
	
	@PostConstruct
	private void init()
	{		
		this.disableActionMenu();
		this.select_enactor_boundary.setMain_boundary(this);
		this.select_super_boundary.setMain_boundary(this);
	}
	
	
	public void setCurrent_user(CurrentUser current_user) {
		this.current_user = current_user;
	}


	public void setSelect_enactor_boundary(EnactorTable select_enactor_boundary) {
		this.select_enactor_boundary = select_enactor_boundary;
	}

	
	public void setSelect_super_boundary(SuperTable select_super_boundary) {
		this.select_super_boundary = select_super_boundary;
	}


	public void setGo_activity_control(ActivityGOControl go_activity_control) {
		this.go_activity_control = go_activity_control;
	}	

	
	public void setExplorer_boundary(ExplorerGOBoundary explorer_boundary) {
		this.explorer_boundary = explorer_boundary;
	}

	//------------------------------------------------------------------------------------setter and getter methods for render fields
	
	public boolean isRender_save_action() {
		return render_save_action;
	}

	public void setRender_save_action(boolean render_save_action) {
		this.render_save_action = render_save_action;
	}

	public boolean isRender_delete_action() {
		return render_delete_action;
	}

	public void setRender_delete_action(boolean render_delete_action) {
		this.render_delete_action = render_delete_action;
	}

	public boolean isRender_close_action() {
		return render_close_action;
	}

	public void setRender_close_action(boolean render_close_action) {
		this.render_close_action = render_close_action;
	}
	
	public void setRender_goal(boolean render_goal) {
		this.render_goal = render_goal;
	}
	
	public boolean isRender_goal() {
		return render_goal;
	}
	
	public void disableActionMenu()
	{
		this.setRender_save_action(false);
		this.setRender_delete_action(false);
		this.setRender_close_action(false);
	}
	
	public void enableActionMenu()
	{
		this.setRender_save_action(true);
		this.setRender_delete_action(true);
		this.setRender_close_action(true);
	}
	
	//------------------------------------------------------------------------------------setter and getter methods for goal fields
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getStatus() {
		
		String statusToPrint = "";
		
		switch(this.status)
		{
			case DEFINITION : 
				statusToPrint = "In Definition";
				break;
			case ELICITATION_VOTE:
				statusToPrint = "Elicitation Voting";
				break;
			case FEASIBILITY_ANALYSIS:
				statusToPrint = "Feasibility Analysis";
				break;
			case DEVELOPEMENT:
				statusToPrint = "In Developement";
				break;
			case COMPLETED:
				statusToPrint = "Completed";
				break;
			default:
				statusToPrint = "N/A";	
				break;
		}
		return statusToPrint;
	}

	
	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Integer getPriority() {
		if(this.priority == null)
			return new Integer(-1);
		return priority;
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}
	
	public User getGoalOwner() {
		return goalOwner;
	}

	public void setGoalOwner(User goalOwner) {
		this.goalOwner = goalOwner;
	}

	public String getFocus() {
		return focus;
	}

	public void setFocus(String focus) {
		this.focus = focus;
	}

	public String getObject() {
		return object;
	}

	public void setObject(String object) {
		this.object = object;
	}

	public String getMagnitude() {
		return magnitude;
	}

	public void setMagnitude(String magnitude) {
		this.magnitude = magnitude;
	}

	public String getTimeframe() {
		return timeframe;
	}

	public void setTimeframe(String timeframe) {
		this.timeframe = timeframe;
	}

	public String getOrganizationalScope() {
		return organizationalScope;
	}

	public void setOrganizationalScope(String organizationalScope) {
		this.organizationalScope = organizationalScope;
	}

	public String getConstraints() {
		return constraints;
	}

	public void setConstraints(String constraints) {
		this.constraints = constraints;
	}
	
	public User getGoalEnactor() {
		return goalEnactor;
	}

	public void setGoalEnactor(User goalEnactor) {
		this.goalEnactor = goalEnactor;
	}

	public List<User> getSuperList() {
		return superList;
	}

	public void setSuperList(List<User> superList) {
		this.superList = superList;
	}

	public String getRelations() {
		return relations;
	}


	public void setRelations(String relations) {
		this.relations = relations;
	}
	
//-------------------------------------------------------------------------------------------------------------------	



	public void setPropertiesFromOrganizationalGoalObject(OrganizationalGoal current_goal)
	{
		//set text fields
		this.setId					(current_goal.getId());
		this.setTitle				(current_goal.getTitle());
		this.setDescription			(current_goal.getDescription());
		this.setPriority			(current_goal.getPriority());
		this.setFocus				(current_goal.getFocus());
		this.setObject				(current_goal.getObject());
		this.setMagnitude			(current_goal.getMagnitude());
		this.setConstraints			(current_goal.getConstraints());
		this.setOrganizationalScope	(current_goal.getOrganizationalScope());
		this.setTimeframe			(current_goal.getTimeframe());
		this.setRelations			(current_goal.getRelations());
		
		// set goal status
		this.status = current_goal.getEnumStatus();
		
		// set goalOwner
		this.setGoalOwner			(current_goal.getGoalOwner());
		
		// set goalEnactor
		User goalEnactor = current_goal.getGoalEnactor();
		if(goalEnactor != null)
		{
			this.setGoalEnactor(goalEnactor);
			this.select_enactor_boundary.selectUser(goalEnactor);
			this.select_enactor_boundary.setRender_selected_enactor(true);
		}
		else
		{
			this.setGoalEnactor(null);
			this.select_enactor_boundary.selectUser(null);
			this.select_enactor_boundary.setRender_selected_enactor(false);
		}
			
		
		if(current_goal.getSuperList() != null)
		{
			List<User> current_super_list = new ArrayList<User>(current_goal.getSuperList());
			this.setSuperList(current_super_list);
			this.select_super_boundary.setSuper_list(current_super_list);	
		}
			
		else
		{
			this.setSuperList(null);
			this.select_super_boundary.setSuper_list(null);
		}	
		
		//enable render
		this.setRender_goal(true);
		this.enableActionMenu();
	}
		
	
	public void setOrganizationalGoalObjectFromProperties(OrganizationalGoal current_goal)
	{
		current_goal.setId					(this.getId());
		current_goal.setTitle				(this.getTitle());
		current_goal.setDescription			(this.getDescription());
		current_goal.setPriority			(this.getPriority());
		current_goal.setFocus				(this.getFocus());
		current_goal.setObject				(this.getObject());
		current_goal.setMagnitude			(this.getMagnitude());
		current_goal.setConstraints			(this.getConstraints());
		current_goal.setOrganizationalScope	(this.getOrganizationalScope());
		current_goal.setTimeframe			(this.getTimeframe());
		current_goal.setRelations			(this.getRelations());
		
		current_goal.setGoalOwner			(this.getGoalOwner());
		current_goal.setGoalEnactor			(this.getGoalEnactor());
		
		if(this.getSuperList() != null)
		{
			Set<User> selected_super_list = new HashSet<User>(this.getSuperList());
			current_goal.setSuperList(selected_super_list);
		}
		
		this.printOrganizationalGoal(current_goal);
	}
	

	public void createGoal()
	{	
		OrganizationalGoal created_goal = null;
		
		try {
			created_goal = this.go_activity_control.createGoal(this.current_user.getUser());
		} catch (GoalElicitationException e) {
			this.sendMessage("Error", e.getMessage(), FacesMessage.SEVERITY_ERROR);
		}
		
		this.setPropertiesFromOrganizationalGoalObject(created_goal);
		this.current_user.setCurrent_goal(created_goal);
		this.explorer_boundary.addOrganizationalGoal(created_goal);
		this.sendMessage("Info", created_goal.getTitle() + " successfully created!", FacesMessage.SEVERITY_INFO);
	}
	
	
	public void readGoal(Integer goalID)
	{
		if(goalID != null)
		{
			OrganizationalGoal retrieved_goal = null;
			try {
				retrieved_goal = this.go_activity_control.readGoal(goalID, this.current_user.getUser());
			} catch (GoalElicitationException e) {
				this.sendMessage("Error", e.getMessage(), FacesMessage.SEVERITY_ERROR);
			}
			
			if(retrieved_goal==null)
			{
				System.out.println("Goal not found");
					return;
			}
			
			this.setPropertiesFromOrganizationalGoalObject(retrieved_goal);		
			this.current_user.setCurrent_goal(retrieved_goal);
			this.sendMessage("Info", retrieved_goal.getTitle() + " successfully opened!", FacesMessage.SEVERITY_INFO);
		}
	}
	
	public void updateGoal()
	{
		OrganizationalGoal modified_goal = new OrganizationalGoal();
		this.setOrganizationalGoalObjectFromProperties(modified_goal);
		
		try {
			this.go_activity_control.updateGoal(modified_goal, this.current_user.getUser());
		} catch (GoalElicitationException e) {
			this.sendMessage("Error", e.getMessage(), FacesMessage.SEVERITY_ERROR);
		}
		
		this.explorer_boundary.removeOrganizationalGoal(this.current_user.getCurrent_goal());
		this.current_user.setCurrent_goal(modified_goal);
		this.explorer_boundary.addOrganizationalGoal(this.current_user.getCurrent_goal());
		this.sendMessage("Info", modified_goal.getTitle() + " successfully saved!", FacesMessage.SEVERITY_INFO);
	}
	
	public void deleteGoal()
	{
		System.out.println("Calling a delete Org Goal");
		OrganizationalGoal current_goal = this.current_user.getCurrent_goal();
		
		if(current_goal != null)
		{
			try {
				this.go_activity_control.deleteGoal(current_goal.getId(), this.current_user.getUser());
			} catch (GoalElicitationException e) {
				this.sendMessage("Error", e.getMessage(), FacesMessage.SEVERITY_ERROR);
			}
			this.sendMessage("Info", current_goal.getTitle() + " successfully deleted!", FacesMessage.SEVERITY_INFO);
			this.explorer_boundary.removeOrganizationalGoal(current_goal);
			this.closeGoal();
		}
		else
			sendMessage("Info", "no goal is selected for delete", FacesMessage.SEVERITY_WARN);
	}
	
	public void closeGoal()
	{
		this.current_user.setCurrent_goal(null);
		this.setRender_goal(false);
		this.disableActionMenu();
	}
	
	public void closeWithSave()
	{
		this.updateGoal();
		this.current_user.setCurrent_goal(null);
		this.setRender_goal(false);
		this.disableActionMenu();
	}
	
	
	private void sendMessage(String summary, String detail, Severity severity)
	{
		FacesMessage message = new FacesMessage(summary, detail);
		message.setSeverity(severity);
		FacesContext context = FacesContext.getCurrentInstance();  
		context.addMessage(null, message);  
	}
	
	
	private void printOrganizationalGoal(OrganizationalGoal to_print)
	{

		System.out.println("title:\t\t"+to_print.getTitle());
		System.out.println("description:\t\t"+to_print.getDescription());
		System.out.println("priority:\t\t"+to_print.getPriority());
		System.out.println("focus:\t\t"+to_print.getFocus());
		System.out.println("object:\t\t"+to_print.getObject());
		System.out.println("magnitude:\t\t"+to_print.getMagnitude());
		System.out.println("constrains:\t\t"+to_print.getConstraints());
		System.out.println("organizational scope:\t\t"+to_print.getOrganizationalScope());
		System.out.println("time frame:\t\t"+to_print.getTimeframe());
		System.out.println("relations:\t\t"+to_print.getRelations());
		System.out.println("owner:");
		System.out.println("\tusername:\t"+to_print.getGoalOwner().getUsername());
		System.out.println("\trole:\t"+to_print.getGoalOwner().getRole().getTitle());
		
		if(to_print.getGoalEnactor() != null)
		{
			System.out.println("enactor:");
			System.out.println("\tusername:\t"+to_print.getGoalEnactor().getUsername());
			System.out.println("\trole:\t"+to_print.getGoalEnactor().getRole().getTitle());
			
		}
		
		if(to_print.getSuperList()==null)
		{
			System.out .println("\tno super assigned");
		}
		else
		{
			Iterator super_it = to_print.getSuperList().iterator();
			
			while(super_it.hasNext())
			{
				System.out.println("super:");
				User super_u = (User) super_it.next();
				System.out.println("\tusername:\t"+super_u.getUsername());
				System.out.println("\trole:\t"+super_u.getRole().getTitle());
				System.out.println("----------------------------------------------------------------------");
			}
		}
	}
	
	
}
